package com.cskt.petproject178.handler;

import com.cskt.petproject178.pojo.Authened;
import com.cskt.petproject178.pojo.exception.BaseException;
import com.cskt.petproject178.pojo.vo.ResultVO;
import com.cskt.petproject178.pojo.vo.StatusEnum;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.annotation.Annotation;

/**
 * 自定义认证拦截器
 *
 * @author 27013
 **/

@Component
public class Authenticationhandler implements HandlerInterceptor {
    private static final Logger log= LoggerFactory.getLogger(Authenticationhandler.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //判断目前类或者方法上有没有对应的注解，因为有注解表示需要经过认证；否则不需要
        //判断hander是否是HandlerMethod类型，如果不是直接放行
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //通过反射获取目标方法上的注解
            Authened annotation = handlerMethod.getMethodAnnotation(Authened.class);
            //判断该注解是否存在，如果存在，则需要判断登录状态
            if (ObjectUtils.isEmpty(annotation)) {
                //验证类上面有没有对应的注解
                //获取目标类
                Class<?> targetClass = handlerMethod.getBeanType();
                Authened classAnntation = targetClass.getAnnotation(Authened.class);
                if (ObjectUtils.isEmpty(classAnntation)) {
                    //该类不需要认证，直接方行
                    return true;
                }
            }
        }
    //目标方法或者目标类上有注解
        //获取目标方法的参数->token
        String token = request.getHeader("token");
        String tokenKey = "pet:token:"+token;
        if (!StringUtils.hasText(token)) {
            log.error("token为空");
          throw  new BaseException(StatusEnum.AUTH_TOKEN_EMPTY) ;
        }
        String userStr = stringRedisTemplate.opsForValue().get(tokenKey);
        if (!StringUtils.hasText(userStr)) {
            log.warn("当前用户未登录，无法添加购物车商品{}",token);
          throw  new BaseException(StatusEnum.AUTH_USER_NOT_LOGIN);
        }
        return true;
    }
}
